/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * @author 品讯科技
 */

package com.px.pa.modulars.circle.controller;

import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pig.common.core.util.R;
import com.px.basic.alone.security.annotation.Inner;
import com.px.pa.constants.TopicEnum;
import com.px.pa.modulars.circle.entity.*;
import com.px.pa.modulars.circle.service.*;
import com.px.pa.modulars.circle.vo.LearningBackVo;
import com.px.pa.modulars.circle.vo.QuestionsSetVo;
import com.px.pa.modulars.circle.vo.ScoreVo;
import com.px.plugins.conversion.excel.util.ExcelBaseUtil;
import org.apache.commons.collections.list.AbstractLinkedList;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 试卷表
 *
 * @author 品讯科技
 * @date 2024-08
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/circleexaminationpaper")
@Api(value = "circleexaminationpaper", tags = "试卷表管理")
public class CircleExaminationPaperController {

    private final CircleExaminationPaperService circleExaminationPaperService;
    private final CircleTestQuestionsService circleTestQuestionsService;
    private final CircleLearningBackageService circleLearningBackageService;
    private final CircleTestScoreService circleTestScoreService;
    private final CircleUserService circleUserService;
    private final CircleTestQuestionsItemService circleTestQuestionsItemService;
    private final CircleActivitySignService circleActivitySignService;

    /**
     * 分页查询
     *
     * @param page                   分页对象
     * @param circleExaminationPaper 试卷表
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
    @Inner(value = false)
    //@PreAuthorize("@pms.hasPermission('circleExaminationPaper_circleexaminationpaper_get')")
    public R getCircleExaminationPaperPage(Page page, CircleExaminationPaper circleExaminationPaper) {
        Page<CircleExaminationPaper> circleExaminationPaperPage = circleExaminationPaperService.page(page, new QueryWrapper<CircleExaminationPaper>()
                .like(StringUtils.isNotEmpty(circleExaminationPaper.getName()), "name", circleExaminationPaper.getName())
                .eq(circleExaminationPaper.getLearningBackage() != null, "learning_backage", circleExaminationPaper.getLearningBackage())
                .between(circleExaminationPaper.getTime()[0] != null & circleExaminationPaper.getTime()[1] != null,
                        "create_time", circleExaminationPaper.getStartTime(), circleExaminationPaper.getEndTime())
                .orderByDesc("create_time"));
        circleExaminationPaperPage.getRecords().forEach(circleExaminationPaper1 -> {

            CircleLearningBackage circleLearningBackage = circleLearningBackageService.getById(circleExaminationPaper1.getLearningBackage());
            if (circleLearningBackage != null) {
                circleExaminationPaper1.setLearningBackageName(circleLearningBackage.getName());
            }
            //考试题数
            Integer questionsNum = circleTestQuestionsService.count(new QueryWrapper<CircleTestQuestions>().eq("examination_paper", circleExaminationPaper1.getId()));
            circleExaminationPaper1.setQuestionsNum(questionsNum);
            //考试人数
            Integer participants = circleTestScoreService.count(new QueryWrapper<CircleTestScore>().eq("examination_paper", circleExaminationPaper1.getId()));
            circleExaminationPaper1.setParticipants(participants);

            ThreadUtil.execute(() -> {
                // 没有考试完成  时间结束自动提交
                List<CircleTestScore> circleTestScoreList = circleTestScoreService.list(new QueryWrapper<CircleTestScore>().eq("status", 1));
                circleTestScoreList.forEach(circleTestScore -> {
                    Date startDate = Date.from(circleTestScore.getStartTime().toInstant(ZoneOffset.of("+8")));
                    int min = circleActivitySignService.getTime(startDate, new Date());
                    if (circleTestScore.getStatus() == 1) {
                        if (min > circleExaminationPaper1.getLengthTime()) {
                            circleTestScore.setScore(circleTestScore.getScoreRecord());
                            circleTestScore.setLengthTime(circleExaminationPaper1.getLengthTime());
                            circleTestScore.setStatus(2);
                            circleTestScoreService.updateById(circleTestScore);
                        }
                    }
                });
            });

        });
        return R.ok(circleExaminationPaperPage);
    }


    /**
     * 通过id查询试卷表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
    //@PreAuthorize("@pms.hasPermission('circleExaminationPaper_circleexaminationpaper_get')")
    @Inner(value = false)
    public R getById(@PathVariable("id") Integer id, @RequestParam(required = false) Integer topic, @RequestParam(required = false, defaultValue = "1") Integer page,
                     @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        CircleExaminationPaper circleExaminationPaper = circleExaminationPaperService.getById(id);
        Page<CircleTestQuestions> circleTestQuestionsPage = circleTestQuestionsService.page(new Page(page, pageSize), new QueryWrapper<CircleTestQuestions>()
                .eq("examination_paper", id).eq(topic != null, "topic", topic)
                .orderByDesc("create_time"));
        circleTestQuestionsPage.getRecords().forEach(circleTestQuestions -> {

            List<CircleTestQuestionsItem> circleTestQuestionsItemList = circleTestQuestionsItemService.list(new QueryWrapper<CircleTestQuestionsItem>().eq("test_questions", circleTestQuestions.getId()));

            if (circleTestQuestions.getTopic().equals(TopicEnum.TOPIC_ENUM_THREE.getValue())) {
                circleTestQuestions.setCircleTestQuestionsItemLists(circleTestQuestionsItemList);
            } else {
                circleTestQuestions.setCircleTestQuestionsItemList(circleTestQuestionsItemList);
            }

        });

        //考试人数
        Integer participants = circleTestScoreService.count(new QueryWrapper<CircleTestScore>().eq("examination_paper", id));
        circleExaminationPaper.setTestPeople(participants);
        //及格人数
        Integer qualifiedPeople = circleTestScoreService.count(new QueryWrapper<CircleTestScore>().eq("examination_paper", id)
                .ge("score", circleExaminationPaper.getPassingScore()));
        circleExaminationPaper.setQualifiedPeople(qualifiedPeople);

        //  circleExaminationPaper.setCircleTestQuestionsList(circleTestQuestionsPage.getRecords());
        circleExaminationPaper.setCircleTestQuestionsPage(circleTestQuestionsPage);
        // 考试题类型数
        circleExaminationPaper.setRadioNum(circleTestQuestionsService.getCountByexaminationPaper(id, TopicEnum.TOPIC_ENUM_ONE.getValue()));
        circleExaminationPaper.setMultipleNum(circleTestQuestionsService.getCountByexaminationPaper(id, TopicEnum.TOPIC_ENUM_TWO.getValue()));
        circleExaminationPaper.setJudgmentNum(circleTestQuestionsService.getCountByexaminationPaper(id, TopicEnum.TOPIC_ENUM_THREE.getValue()));
        CircleLearningBackage circleLearningBackage = circleLearningBackageService.getById(circleExaminationPaper.getLearningBackage());
        if (circleLearningBackage != null) {
            circleExaminationPaper.setLearningBackageName(circleLearningBackage.getName());
        }
        return R.ok(circleExaminationPaper);
    }

    /**
     * 新增试卷表
     *
     * @param circleExaminationPaper 试卷表
     * @return R
     */
    @ApiOperation(value = "新增试卷表", notes = "新增试卷表")
    @PostMapping
    //@PreAuthorize("@pms.hasPermission('circleExaminationPaper_circleexaminationpaper_add')")
    @Inner(value = false)
    public R save(@RequestBody CircleExaminationPaper circleExaminationPaper) {
        List<QuestionsSetVo> questionsSetVoList = circleExaminationPaperService.getJson(circleExaminationPaper.getQuestionsSet());
        Integer num = 0;
        Integer num1 = 0; //单选
        Integer num2=0; //多选
        Integer num3 =0; //判断
        Integer count1 = 0; //单选试题数
        Integer count2 = 0; //多选试题数
        Integer count3 = 0; //判断试题数
        for (QuestionsSetVo questionsSetVo : questionsSetVoList) {
            num = num + questionsSetVo.getNum();
            if(questionsSetVo.getType() == 1){
                num1 =  questionsSetVo.getNum();
            }else if(questionsSetVo.getType() == 2){
                num2 =  questionsSetVo.getNum();
            }else if (questionsSetVo.getType() == 3){
                num3 =  questionsSetVo.getNum();
            }
        }

        if(circleExaminationPaper.getCircleTestQuestionsList().size() < num){
            return R.failed("题数不够不能新增！");
        }else {

            List<CircleTestQuestions> circleTestQuestionsList = circleExaminationPaper.getCircleTestQuestionsList();
            for (CircleTestQuestions circleTestQuestions:circleTestQuestionsList) {
                if(circleTestQuestions.getTopic() == 1){
                    count1 = count1 +1;
                }else if(circleTestQuestions.getTopic() == 2){
                    count2 = count2 + 1;

                }else if(circleTestQuestions.getTopic() == 3){
                    count3 = count3 + 1;
                }

            }
            if(num1 > count1){
                return R.failed("单选题不够，不能添加");
            }
            if(num2 > count2){
                return R.failed("多选题不够，不能添加");
            }

            if(num3 > count3){
                return R.failed("判断题不够，不能添加");
            }

        }

        circleExaminationPaper.setCreateTime(LocalDateTime.now());
        circleExaminationPaperService.save(circleExaminationPaper);
        //添加考试题目和选项

        circleExaminationPaperService.addNow(circleExaminationPaper.getCircleTestQuestionsList(), circleExaminationPaper.getId());
        return R.ok();
    }

    /**
     * 修改试卷表
     *
     * @param circleExaminationPaper 试卷表
     * @return R
     */
    @ApiOperation(value = "修改试卷表", notes = "修改试卷表")
    @PutMapping
    // @PreAuthorize("@pms.hasPermission('circleExaminationPaper_circleexaminationpaper_edit')")
    @Inner(value = false)
    public R updateById(@RequestBody CircleExaminationPaper circleExaminationPaper) {
        List<QuestionsSetVo> questionsSetVoList = circleExaminationPaperService.getJson(circleExaminationPaper.getQuestionsSet());
        Integer num = 0;
        Integer num1 = 0; //单选
        Integer num2=0; //多选
        Integer num3 =0; //判断
        Integer count1 = 0; //单选试题数
        Integer count2 = 0; //多选试题数
        Integer count3 = 0; //判断试题数
        Integer count = 0; //题型数
        for (QuestionsSetVo questionsSetVo : questionsSetVoList) {
            num = num + questionsSetVo.getNum();
            if(questionsSetVo.getType() == 1){
                num1 =  questionsSetVo.getNum();
            }else if(questionsSetVo.getType() == 2){
                num2 =  questionsSetVo.getNum();
            }else if (questionsSetVo.getType() == 3){
                num3 =  questionsSetVo.getNum();
            }
        }

        count = circleTestQuestionsService.count(new QueryWrapper<CircleTestQuestions>()
                .eq("examination_paper",circleExaminationPaper.getId()));
        if(count < num){
            return R.failed("题数不够不能新增！");
        }else {
            count1 = circleTestQuestionsService.count(new QueryWrapper<CircleTestQuestions>()
                    .eq("examination_paper",circleExaminationPaper.getId()).eq("topic",1));
            if(num1 > count1){
                return R.failed("单选题不够，不能添加");
            }
            count2 = circleTestQuestionsService.count(new QueryWrapper<CircleTestQuestions>()
                    .eq("examination_paper",circleExaminationPaper.getId()).eq("topic",2));
            if(num2 > count2){
                return R.failed("多选题不够，不能添加");
            }
            count3 = circleTestQuestionsService.count(new QueryWrapper<CircleTestQuestions>()
                    .eq("examination_paper",circleExaminationPaper.getId()).eq("topic",3));

            if(num3 > count3){
                return R.failed("判断题不够，不能添加");
            }

        }
        return R.ok(circleExaminationPaperService.updateById(circleExaminationPaper));
    }

    /**
     * 通过id删除试卷表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除试卷表", notes = "通过id删除试卷表")
    @DeleteMapping("/{id}")
    // @PreAuthorize("@pms.hasPermission('circleExaminationPaper_circleexaminationpaper_del')")
    @Inner(value = false)
    public R removeById(@PathVariable Integer id) {
        return R.ok(circleExaminationPaperService.removeById(id));
    }

    /**
     * 学习包列表 筛选出已经关联考试的学习包
     */
    @ApiOperation(value = "学习包列表", notes = "学习包列表")
    @GetMapping("/learning/list")
    public R getList() {
        List<CircleExaminationPaper> circleExaminationPaperList = circleExaminationPaperService.list();
        List<Integer> list = new ArrayList<>();
        circleExaminationPaperList.forEach(circleExaminationPaper -> {
            list.add(circleExaminationPaper.getLearningBackage());
        });
        List<CircleLearningBackage> circleLearningBackageList = circleLearningBackageService.list(new QueryWrapper<CircleLearningBackage>().notIn(list.size() > 0, "id", list));
        return R.ok(circleLearningBackageList);
    }

    /**
     * 成绩导出
     */
    @ApiOperation(value = "成绩导出", notes = "成绩导出")
    @GetMapping("/score/excel")
    @Inner(value = false)
    public void excel(@RequestParam("examinationPaper") Integer examinationPaper, HttpServletResponse response, HttpServletRequest request) {
        CircleExaminationPaper circleExaminationPaper = circleExaminationPaperService.getById(examinationPaper);
        List<CircleTestScore> circleTestScoreList = circleTestScoreService.list(new QueryWrapper<CircleTestScore>().eq("examination_paper", examinationPaper));
        List<ScoreVo> scoreVoList = new ArrayList<>();
        circleTestScoreList.forEach(circleTestScore -> {
            ScoreVo scoreVo = new ScoreVo();
            CircleUser circleUser = circleUserService.getById(circleTestScore.getUid());
            if (circleUser != null) {
                scoreVo.setUname(circleUser.getName());
            }
            if (circleTestScore.getScore() != null) {
                if (circleTestScore.getScore() >= circleExaminationPaper.getPassingScore()) {
                    scoreVo.setStatus("合格");
                } else {
                    scoreVo.setStatus("不合格");
                }
            }

            scoreVo.setScore(circleTestScore.getScore());
            scoreVoList.add(scoreVo);

        });

        ExcelBaseUtil.exportExcel(scoreVoList, circleExaminationPaper.getName(), "考试成绩信息", ScoreVo.class, "考试成绩.xls", response);
    }

    /**
     * @return
     */
    @GetMapping("/list")
    @Inner(value = false)
    public R get() {
        circleExaminationPaperService.createList(60, 41);
        return R.ok();
    }


    /**
     * 关联学习包列表
     */

    @GetMapping("/learningList")
    @Inner(value = false)
    public R getList1() {
        List<CircleLearningBackage> circleLearningBackageList = circleLearningBackageService.list();
        List<LearningBackVo> learningBackVoList = new ArrayList<>();
        circleLearningBackageList.forEach(circleLearningBackage -> {
            LearningBackVo learningBackVo = new LearningBackVo();

            learningBackVo.setId(circleLearningBackage.getId());
            learningBackVo.setName(circleLearningBackage.getName());
            learningBackVoList.add(learningBackVo);
        });

        return R.ok(learningBackVoList);

    }


    /**
     * 考试是否开启
     */
    @GetMapping("/isOpen")
    @Inner(value = false)
    public R getOpen(@RequestParam("examinationPaper") Integer examinationPaper) {


        CircleExaminationPaper circleExaminationPaper = circleExaminationPaperService.getById(examinationPaper);
        List<QuestionsSetVo> questionsSetVoList = circleExaminationPaperService.getJson(circleExaminationPaper.getQuestionsSet());
        Integer num = 0;
        for (QuestionsSetVo questionsSetVo : questionsSetVoList) {
            num = num + questionsSetVo.getNum();
        }

        int count = circleTestQuestionsService.count(new QueryWrapper<CircleTestQuestions>().eq("examination_paper", examinationPaper));
        if (count < num) {
            return R.failed("考试题目小于考试设置题不能开启");
        }
        if (circleExaminationPaper.getIsOpen() == 2) {
            circleExaminationPaper.setIsOpen(1);
            circleExaminationPaperService.updateById(circleExaminationPaper);
        } else {
            return R.failed("考试已开启不能关闭");
        }
        return R.ok();
    }


}
